package tech.shupi.babytaptv

import android.content.Context
import android.util.Log
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import java.security.cert.X509Certificate
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

/**
 * 文件访问服务
 * 为 BabyTapTV 提供文件下载和本地存储能力
 */
class FileAccessService(private val context: Context) {

    companion object {
        private const val TAG = "FileAccessService"
    }

    private val okHttpClient: OkHttpClient by lazy {
        // 创建一个 TrustManager，用于信任自签名证书
        val trustManagers = arrayOf<TrustManager>(
            object : X509TrustManager {
                override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
                    // 信任所有客户端证书
                }

                override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
                    // 信任所有服务器证书
                }

                override fun getAcceptedIssuers(): Array<X509Certificate> {
                    return arrayOf()
                }
            }
        )

        // 创建一个 SSLContext
        val sslContext = SSLContext.getInstance("TLS")
        sslContext.init(null, trustManagers, java.security.SecureRandom())

        // 创建 OkHttpClient.Builder 并设置 TLS 协议
        OkHttpClient.Builder()
            .sslSocketFactory(sslContext.socketFactory, trustManagers[0] as X509TrustManager)
            .hostnameVerifier { _, _ -> true }
            .build()
    }

    /**
     * 检查文件是否存在
     */
    fun fileExists(relativePath: String): Boolean {
        try {
            val file = File(context.filesDir, relativePath)
            val exists = file.exists()
            Log.d(TAG, "检查文件是否存在: ${file.absolutePath}, 结果: $exists")
            return exists
        } catch (e: Exception) {
            Log.e(TAG, "检查文件是否存在失败: $relativePath", e)
            return false
        }
    }

    /**
     * 获取文件大小
     */
    fun getFileSize(relativePath: String): Long {
        try {
            val file = File(context.filesDir, relativePath)
            val size = file.length()
            Log.d(TAG, "获取文件大小: ${file.absolutePath}, 大小: $size")
            return size
        } catch (e: Exception) {
            Log.e(TAG, "获取文件大小失败: $relativePath", e)
            return -1
        }
    }

    /**
     * 读取文件内容
     */
    fun readFile(relativePath: String): ByteArray? {
        try {
            val file = File(context.filesDir, relativePath)
            Log.d(TAG, "读取文件: ${file.absolutePath}")
            
            if (!file.exists()) {
                Log.w(TAG, "文件不存在: ${file.absolutePath}")
                return null
            }

            val inputStream = FileInputStream(file)
            val bytes = inputStream.readBytes()
            inputStream.close()
            
            Log.d(TAG, "文件读取成功: ${file.absolutePath}, 大小: ${bytes.size}")
            return bytes
        } catch (e: Exception) {
            Log.e(TAG, "读取文件失败: $relativePath", e)
            return null
        }
    }

    /**
     * 下载文件到本地
     */
    fun downloadFile(remoteUrl: String, localPath: String, callback: (Boolean, String?) -> Unit) {
        try {
            Log.d(TAG, "开始下载文件: $remoteUrl -> $localPath")
            
            // 确保目录存在
            val localFile = File(context.filesDir, localPath)
            val parentDir = localFile.parentFile
            if (parentDir != null && !parentDir.exists()) {
                parentDir.mkdirs()
                Log.d(TAG, "创建目录: ${parentDir.absolutePath}")
            }
            
            val request = Request.Builder()
                .url(remoteUrl)
                .get()
                .build()

            val call = okHttpClient.newCall(request)

            call.enqueue(object : okhttp3.Callback {
                override fun onFailure(call: Call, e: IOException) {
                    Log.e(TAG, "下载文件失败: $remoteUrl", e)
                    callback(false, e.message)
                }

                override fun onResponse(call: Call, response: Response) {
                    try {
                        Log.d(TAG, "下载响应状态: ${response.code}")
                        val responseBody = response.body
                        if (response.isSuccessful && responseBody != null) {
                            val bytes = responseBody.bytes()
                            Log.d(TAG, "下载文件大小: ${bytes.size} bytes")
                            
                            // 写入本地文件
                            val outputStream = FileOutputStream(localFile)
                            outputStream.write(bytes)
                            outputStream.close()
                            
                            Log.d(TAG, "文件下载成功: ${localFile.absolutePath}")
                            callback(true, null)
                        } else {
                            Log.e(TAG, "下载响应错误: HTTP ${response.code}")
                            callback(false, "HTTP ${response.code}")
                        }
                    } catch (e: Exception) {
                        Log.e(TAG, "处理下载响应失败", e)
                        callback(false, e.message)
                    }
                }
            })
        } catch (e: Exception) {
            Log.e(TAG, "下载文件异常", e)
            callback(false, e.message)
        }
    }

    /**
     * 获取文件的 MIME 类型
     */
    fun getMimeType(relativePath: String): String {
        return when {
            relativePath.endsWith(".jpg", true) || relativePath.endsWith(".jpeg", true) -> "image/jpeg"
            relativePath.endsWith(".png", true) -> "image/png"
            relativePath.endsWith(".gif", true) -> "image/gif"
            relativePath.endsWith(".webp", true) -> "image/webp"
            relativePath.endsWith(".mp3", true) -> "audio/mpeg"
            relativePath.endsWith(".wav", true) -> "audio/wav"
            else -> "application/octet-stream"
        }
    }

    /**
     * 列出目录中的文件
     */
    fun listFiles(relativePath: String): Array<String> {
        try {
            val dir = File(context.filesDir, relativePath)
            if (!dir.exists() || !dir.isDirectory) {
                Log.w(TAG, "目录不存在或不是目录: ${dir.absolutePath}")
                return emptyArray()
            }

            val files = dir.listFiles()
            val fileNames = files?.map { it.name }?.toTypedArray() ?: emptyArray()
            Log.d(TAG, "列出目录文件: ${dir.absolutePath}, 文件数: ${fileNames.size}")
            return fileNames
        } catch (e: Exception) {
            Log.e(TAG, "列出目录文件失败: $relativePath", e)
            return emptyArray()
        }
    }

    /**
     * 删除文件
     */
    fun deleteFile(relativePath: String): Boolean {
        try {
            val file = File(context.filesDir, relativePath)
            val deleted = file.delete()
            Log.d(TAG, "删除文件: ${file.absolutePath}, 结果: $deleted")
            return deleted
        } catch (e: Exception) {
            Log.e(TAG, "删除文件失败: $relativePath", e)
            return false
        }
    }
} 